package com.cloudbroker.bcs.platform.ltb.middle.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cloudbroker.bcs.common.configure.ConfigUtil;
import com.cloudbroker.bcs.platform.ltb.common.util.CacheHelper;
import com.cloudbroker.bcs.platform.ltb.middle.entity.ChatMsg;
import com.cloudbroker.bcs.platform.ltb.middle.service.ChatMsgService;
import com.cloudbroker.bcs.platform.ltb.middle.util.SHA1Util;
import com.cloudbroker.bcs.platform.ltb.middle.util.ssl.SSLHttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**
 * Created by world on 17/1/16.
 */
@Service
public class RongYunIMHistoryTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(RongYunIMHistoryTask.class);

    @Resource
    private ChatMsgService chatMsgService;

    private final static String CHAT_TASK_SUCCESS_LIST = "chatHistoryTask";

    private final static String HISTORY_SAVE_PATH = "/tmp/";
    public void execute() {
        try {
            CacheHelper cacheHelper = CacheHelper.getInstance();
            String uuid = UUID.randomUUID().toString();
            SimpleDateFormat ft = new SimpleDateFormat ("yyyyMMddHH");
            String logTime = ft.format(new Date());

            //判断是否已经拉取聊天历史日志成功
            if (cacheHelper.sismember(CHAT_TASK_SUCCESS_LIST,logTime)){
                return;
            }
            String lockKey = "chatHistoryTask." + logTime;
            try{
                Long lock = cacheHelper.setnx(lockKey, uuid, 60*60);
                //被锁了则不执行
                if (lock == 0) {
                    return;
                }else {
                    String downloadURL = getDownloadURL();
                    if (downloadURL == null || downloadURL.equals("")){
                        LOGGER.info("download url is empty!");
                        return;
                    }else {
                        LOGGER.info("download url is:" + downloadURL);
                    }
                    String fileName = logTime + ".zip";
                    downloadNet(downloadURL, fileName);
                    readZipFile(fileName);
                    cacheHelper.sdd(CHAT_TASK_SUCCESS_LIST, logTime);
                    deleteFile(fileName);
                }

            }catch (Exception e){
            }finally {
                if(cacheHelper.get(lockKey) != null && cacheHelper.get(lockKey).equals(uuid)){
                    cacheHelper.delete(lockKey);
                }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
      返回上一小时的历史记录
     */
    public String getDownloadURL() throws Exception{
        String urlStr = "http://api.cn.ronghub.com/message/history.json";
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        String nonce = String.valueOf(Math.random() * 1000000);
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String appsecret = ConfigUtil.get("rongyun_appsecret");
        StringBuilder toSign = new StringBuilder(appsecret).append(nonce).append(timestamp);

        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setInstanceFollowRedirects(true);
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);

        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        conn.setRequestProperty("App-Key", ConfigUtil.get("rongyun_appkey"));
        conn.setRequestProperty("Nonce", nonce);
        conn.setRequestProperty("Timestamp", timestamp);
        conn.setRequestProperty("signature", SHA1Util.getSha1(toSign.toString()));
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        long time  = System.currentTimeMillis();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyyMMddHH");
        Long getHistoryTime = Long.valueOf(ft.format(new Date(time)));
        getHistoryTime = getHistoryTime-1;//获取上个小时的记录
        StringBuilder sb = new StringBuilder();
        sb.append("&date=").append(URLEncoder.encode(getHistoryTime.toString(), "utf-8"));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1, body.length());
        }
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
        out.write(body.getBytes("utf-8"));
        out.flush();
        out.close();
        InputStream input = null;
        if (conn.getResponseCode() == 200) {
            input = conn.getInputStream();
        } else {
            input = conn.getErrorStream();
        }
        String result = new String(SSLHttpUtil.readInputStream(input), "UTF-8");
        JSONObject jsonObject = JSONObject.parseObject(result);
        return jsonObject.get("url").toString();
    }

    public void readZipFile(String file) throws Exception {
        file = HISTORY_SAVE_PATH + file ;
        ZipFile zf = new ZipFile(file);
        InputStream in = new BufferedInputStream(new FileInputStream(file));
        ZipInputStream zin = new ZipInputStream(in);
        ZipEntry ze;
        while ((ze = zin.getNextEntry()) != null) {
            if (ze.isDirectory()) {
            } else {
                long size = ze.getSize();
                if (size > 0) {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(zf.getInputStream(ze)));
                    String line;
                    while ((line = br.readLine()) != null) {
                        String logContent = line.substring(19,line.length());
                        JSONObject jsonObject = JSON.parseObject(logContent);
                        ChatMsg chatMsg = new ChatMsg();
                        chatMsg.setCompany_id("20020");
                        chatMsg.setClassname(jsonObject.getString("classname"));
                        chatMsg.setContent(jsonObject.getJSONObject("content").getString("content"));
                        chatMsg.setExtra(jsonObject.getJSONObject("content").getString("extra"));
                        chatMsg.setFrom_user_id(jsonObject.getLong("fromUserId"));
                        chatMsg.setTarget_id(jsonObject.getLong("targetId"));
                        chatMsg.setTargetType(jsonObject.getInteger("targetType"));
                        chatMsg.setGroupId(jsonObject.getString("GroupId"));
                        chatMsg.setDateTime(jsonObject.getString("dateTime"));
                        chatMsg.setMsgUID(jsonObject.getString("msgUID"));
                        chatMsg.setSource(jsonObject.getString("source"));
                        chatMsgService.save(chatMsg);
                    }
                    br.close();
                }
            }
        }
        zin.closeEntry();
    }

    public void downloadNet(String downloadURL,String fileName) {
        // 下载网络文件
        int bytesum = 0;
        int byteread = 0;
        try {
            URL url = new URL(downloadURL);
            URLConnection conn = url.openConnection();
            InputStream inStream = conn.getInputStream();
            FileOutputStream fs = new FileOutputStream(HISTORY_SAVE_PATH + fileName);

            byte[] buffer = new byte[1204];
            int length;
            while ((byteread = inStream.read(buffer)) != -1) {
                bytesum += byteread;
                fs.write(buffer, 0, byteread);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean deleteFile(String sPath) {
        boolean flag = false;
        sPath =  HISTORY_SAVE_PATH + sPath;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }
}
